/**
 * Project:   dtu.fmes.googleloon
 * File:      Environment.java
 * License: 
 *            This file is licensed under GNU General Public License version 3
 *            http://www.gnu.org/licenses/gpl-3.0.txt
 *
 * Copyright: Bartosz Cichecki [ cichecki.bartosz@gmail.com ]
 * Date:      Oct 12, 2013
 */

package dtu.fmes.loon.model;

import java.util.Arrays;

import dtu.fmes.loon.model.environment.Area;
import dtu.fmes.loon.model.environment.Time;
import dtu.fmes.loon.model.environment.Wind;

/**
 * 
 * @author Bartosz Cichecki, Nicolai Sonne
 */
public class Environment {

	private Area area;

	private Time time;

	private Wind[][][] winds;

	public Environment() {
		super();
	}

	public Environment(Area area, Time time, Wind[][][] wind) {
		super();
		this.area = area;
		this.time = time;
		winds = wind;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		Environment other = (Environment) obj;
		if (area == null) {
			if (other.area != null) {
				return false;
			}
		} else if (!area.equals(other.area)) {
			return false;
		}
		if (time == null) {
			if (other.time != null) {
				return false;
			}
		} else if (!time.equals(other.time)) {
			return false;
		}
		if (!Arrays.deepEquals(winds, other.winds)) {
			return false;
		}
		return true;
	}

	public Area getArea() {
		return area;
	}

	public Time getTime() {
		return time;
	}

	/**
	 * Splits area into matrix defined by the wind matrix Returns the wind stack relevant for given position. If position is outside the
	 * area, the closest wind stack is returned
	 * 
	 * @param position
	 *            Position of which you want relevant wind array
	 * @return Wind array relevant for position
	 */
	public Wind[] getWindArray(Vector position) {
		Wind[] windArray = new Wind[winds.length];

		int dimensX = winds[0].length;
		int dimensY = winds[0][0].length;

		Double xSize = area.getxSize();
		Double ySize = area.getySize();

		int x = (int) (position.getX() / xSize * dimensY);
		int y = dimensX - 1 - (int) (position.getY() / ySize * dimensX);

		x = x > dimensY - 1 ? dimensY - 1 : x;
		x = x < 0 ? 0 : x;

		y = y > dimensX - 1 ? dimensX - 1 : y;
		y = y < 0 ? 0 : y;

		for (int i = 0; i < winds.length; i++) {
			windArray[i] = winds[i][y][x];
		}

		return windArray;
	}

	public Wind[][][] getWinds() {
		return winds;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (area == null ? 0 : area.hashCode());
		result = prime * result + (time == null ? 0 : time.hashCode());
		result = prime * result + Arrays.hashCode(winds);
		return result;
	}

	public void setArea(Area area) {
		this.area = area;
	}

	public void setTime(Time time) {
		this.time = time;
	}

	public void setWinds(Wind[][][] winds) {
		this.winds = winds;
	}

	@Override
	public String toString() {
		return "Environment [area=" + area + ", time=" + time + ", winds=" + Arrays.toString(winds) + "]";
	}

}
